package com.wtzz.police.base.repository.base;

import com.wtzz.police.base.entity.AbstractIdEntity;
import com.wtzz.police.base.model.exception.WtzzNoRecordException;
import io.swagger.annotations.ApiModel;
import org.hibernate.Hibernate;
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.JpaEntityInformationSupport;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;

import javax.persistence.EntityManager;
import java.io.Serializable;

/**
 * Repository基类实现
 */
public class BaseRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements BaseRepository<T, ID> {

    private JpaEntityInformation<T, ?> entityInformation;
    private EntityManager entityManager;
    private String entityDesc;

    public BaseRepositoryImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {
        super(entityInformation, entityManager);
        this.entityInformation = entityInformation;
        this.entityManager = entityManager;
    }

    public BaseRepositoryImpl(Class<T> domainClass, EntityManager em) {
        this(JpaEntityInformationSupport.getEntityInformation(domainClass, em), em);
    }

    @Override
    public String getEntityDesc() {
        if (entityDesc == null) {
            Class entityClass = entityInformation.getJavaType();
            if (entityClass.isAnnotationPresent(ApiModel.class)) {
                ApiModel anno = (ApiModel) entityClass.getAnnotation(ApiModel.class);
                entityDesc = anno.value();
            } else {
                entityDesc = entityClass.getSimpleName();
            }
        }
        return entityDesc;
    }

    @Override
    public Class<T> getEntityClass() {
        return entityInformation.getJavaType();
    }


    @Override
    public T findByIdUnProxy(ID id) {
        T t = getOne(id);
        return (T) Hibernate.unproxy(t);
    }

    @Override
    public T findByIdOrNull(ID id) {
        return findById(id).orElse(null);
    }

    @Override
    public T findByIdOrThrow(ID id) {
        return findById(id).orElseThrow(() -> new WtzzNoRecordException(getEntityDesc()));
    }

    @Override
    public T findNotLogicalDeleted(ID id) {
        T t  = findByIdOrThrow(id);
        if (t instanceof AbstractIdEntity && ((AbstractIdEntity) t).getDeleted()){
            throw new WtzzNoRecordException(getEntityDesc());
        }
        return t;
    }



}
